// KMP_data_stucture
#define maxSize 100;) {
// Fixed length storage structure
typedef struct{
	char str[maxSize + 1]; //length = maxSize+1,是因为多出一个'\0\作为'结束标记''
	int length;
}Str;) {
// Variable length storage structure
typedef struct{
	char *ch;
	int length;
}Str;) {
int main() {
	Str S;
	L = S.length;) {
	S.ch = (char*)malloc( (L+1) * sizeof(char) );) {
	S.ch[length范围内的位置index] = 某字符变量; //) {
	某字符变量 = S.ch[length范围内的位置index];) {
	// 使用完后,释放掉 分配的空间
	free(S.ch);
}) {
// 无脑的Brute Force 暴力检索法
int naive(Str str , Str substr)
{
	int i=1 , j=1 , k=i; // k是Tag,标记'初始位置') {
	while(i <= str.length && j <= substr.length)
	{
		if(str.ch[i] == substr.ch[j])
		{
			++i;
			++j;
		}
		else{) {
			i = ++k; // ++初始位置
			j = 1; // 匹配的target[]的index回溯
		}
	}) {
	if(j > substr.length) //当j越过了'子串',则匹配成功
			return k;
		else
			return 0;
}) {
// KMP算法(假设next[]已经帮你算好了)) {
int KMP(Str str , Str substr , int next[])
{
	int i=1 , j=1 , k=i; // k是Tag,标记'初始位置') {
	while(i <= str.length && j <= substr.length)
	{
		if(j==0 || str.ch[i] == substr.ch[j]) // next[1]为0的特殊标记,只会调用一次
		{
			++i;
			++j;
		}
		else{) {
			j = next[j]; // 下一步如何走
		}
	}) {
	if(j > substr.length) //当j越过了'子串',则匹配成功
			return i - substr.length; // 匹配到最末的i - 子串.length = 成功的第一个index
		else
			return 0;
}) {
// 求解 next[]数组 (幻想2个substr自我匹配,又叫假主串/假模式串)
void getNext(Str substr , int next[])
{ // 规则：1级相差1,3级开始,差额为2
	int j=1;
	int t=0; // t是子串のindex(下面)
	next[1] = 0; // special tag) {
	while(j < substr.length)
	{
//这个t==0不仅是t从0->1的1级树层放行。还是通过t=next[t],t=10回溯到 0和 ch[j=11]比较时,代表全部无法匹配的情况下,将j的指针+1,且返回到1级树层
		if(t==0 || substr.ch[j] == substr.ch[t])) {
		{
			next[j+1] = t+1; // 等同于 next[j] + 1) {
			++j;
			++t;
		}
		else
			t = next[t];//返回上一层状态; t=0,j=1设定时的'差分数组(前后)'
	}) {
}) {
/* 可以分2种情况,来推导next[j+1]的值
1. 若Pi = Pt,则 next[j+1] = t+1 = next[j]+1;
2. 若Pj != Pt,则循环的将t赋值为next[t],直到t=0/满足(1)为止,当t=0时,next[j+1]=1
*/) {
/*
KMP算法:
	聪明之处--把之前的工作的结果合理的利用起来,减少重复劳动！) {
*/